package com.sitech.ibnms.util;

import java.math.BigInteger;
import java.security.SecureRandom;
import java.util.UUID;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author liujhc <liujhc at si-tech.com.cn>
 */
public class IDUtil {

    /**
     * 有序唯一的整数id(21位整数)
     *
     * @return
     */
    public static BigInteger generateOrderlyNumberId() {
        long mi = System.currentTimeMillis(), na = System.nanoTime() & ((1 << 20) - 1);
        BigInteger bi = BigInteger.valueOf(mi).shiftLeft(28).add(BigInteger.valueOf(na << 8));
        return bi.add(new BigInteger(8, new SecureRandom()));
    }

    /**
     * 有序唯一的字符串id(12位字符串)
     *
     * @return
     */
    public static String generateOrderlyId() {
        return Base62Util.encode(generateOrderlyNumberId());
    }

    /**
     * 经过编码处理的uuid（只包含数字和字母的22位字符串）
     *
     * @return
     */
    public static String randomEncodedUUID() {
        return Base62Util.encodeUUID(UUID.randomUUID());
    }

    /**
     * 通过字符串摘要生成经过编码处理的uuid（只包含数字和字母的22位字符串）
     *
     * @return
     */
    public static String nameEncodedUUID(String name) {
        return Base62Util.encodeUUID(UUID.nameUUIDFromBytes(name.getBytes()));
    }

    public static void main(String[] args) throws InterruptedException {
        //并发重复性测试 10进程*100次调用
        ExecutorService es = Executors.newFixedThreadPool(10);
        final CountDownLatch start = new CountDownLatch(1);
        final CountDownLatch finish = new CountDownLatch(10);
        for (int i = 0; i < 10; i++) {
            es.submit(new Runnable() {
                @Override
                public void run() {
                    try {
                        start.await();
                        for (int i = 0; i < 100; i++) {
                            System.out.println(generateOrderlyId());
                        }
                    } catch (InterruptedException ex) {
                        Logger.getLogger(IDUtil.class.getName()).log(Level.SEVERE, null, ex);
                    } finally {
                        finish.countDown();
                    }
                }
            });
        }
        start.countDown();
        finish.await();
        es.shutdownNow();
    }
}
